﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SqlServer.Dts.Runtime; // Requires reference to Microsoft.SQLServer.ManagedDTS

namespace ToddMcDermid.SSIS
{
    #region CLASS: PauseTask
    [DtsTask(
        DisplayName = "Pause Task",
        TaskType = "General",
        TaskContact = "Todd McDermid",
        IconResource = "ToddMcDermid.SSIS.PauseTask.ico",
        UITypeName = "ToddMcDermid.SSIS.PauseTaskInterface,PauseTask90,Version=1.0.0.0,Culture=Neutral,PublicKeyToken=7415b8b05f59ca43",
        RequiredProductLevel = DTSProductLevel.None)]
    public class PauseTask : Task
    {
        #region Enumerations
        public enum PauseTypes
        {
            ElapsedTime,
            UntilTime
        }
        #endregion

        #region Private Variables
        private PauseTypes _pauseType;
        private int _pauseFor;
        private string _pauseUntil;
        #endregion

        #region Constructor
        /// <summary>
        /// A parameter-less constructor is required for Tasks.
        /// You can place any "initial setup" code in here - but there typically is none.
        /// Most configuration will occur in your public properties.
        /// </summary>
        public PauseTask()
        { }
        #endregion

        #region Public Properties
        /// <summary>
        /// Indicates whether the component will wait delay for a
        /// number of milliseconds (specified in PauseFor), or will
        /// delay until a certain time (specified in PauseUntil)
        /// </summary>
        public PauseTypes PauseType
        {
            get { return this._pauseType; }
            set { this._pauseType = value; }
        }

        /// <summary>
        /// The number of milliseconds to pause for, if PauseType
        /// is set to ElapsedTime
        /// </summary>
        public int PauseFor
        {
            get { return this._pauseFor; }
            set 
            {
                if (value >= 0)
                {
                    this._pauseFor = value;
                }
            }
        }

        /// <summary>
        /// The time to pause until, if PauseType is set to UntilTime
        /// </summary>
        public string PauseUntil
        {
            get { return this._pauseUntil; }
            set
            {
                try
                {
                    string datePlusTime = DateTime.Today.ToString("yyyy-MM-dd ") + value;
                    DateTime sampleDateTime = Convert.ToDateTime(datePlusTime);
                    this._pauseUntil = value;
                }
                catch
                {
                    throw new ArgumentException("Invalid time value '" + value + "' - please specify time only (no date), in hh:mm:ss.fff format.");
                }
            }
        }
        #endregion

        #region Task Implementation
        #region InitializeTask
        /// <summary>
        /// This method is called when the Task is initially placed on the design surface,
        /// before Validate is called, before Execute is called, and before any properties
        /// are read or written to (by the SSIS engine).
        /// </summary>
        public override void InitializeTask(Connections connections, VariableDispenser variableDispenser,
            IDTSInfoEvents events, IDTSLogging log, EventInfos eventInfos,
            LogEntryInfos logEntryInfos, ObjectReferenceTracker refTracker)
        {
            base.InitializeTask(connections, variableDispenser, events, log, eventInfos, logEntryInfos, refTracker);

            this._pauseType = PauseTypes.ElapsedTime;
            this._pauseFor = 1000;
            this._pauseUntil = "";
        }
        #endregion

        #region Validate
        public override DTSExecResult Validate(Connections connections, VariableDispenser variableDispenser, IDTSComponentEvents componentEvents, IDTSLogging log)
        {
            if ((this._pauseType == PauseTypes.ElapsedTime) && (this.PauseFor <= 0))
            {
                componentEvents.FireError(0, "", "Length of pause has not been specified.", "", 0);
                return DTSExecResult.Failure;
            }
            else
            {
                try
                {
                    string datePlusTime = DateTime.Today.ToString("yyyy-MM-dd ") + this.PauseUntil;
                    DateTime sampleDateTime = Convert.ToDateTime(datePlusTime);
                }
                catch
                {
                    return DTSExecResult.Failure;
                }
            }
            return DTSExecResult.Success;
        }
        #endregion

        #region Execute
        public override DTSExecResult Execute(Connections connections, VariableDispenser variableDispenser, IDTSComponentEvents componentEvents, IDTSLogging log, object transaction)
        {
            if (this.PauseType == PauseTypes.ElapsedTime)
            {
                System.Threading.Thread.Sleep(this.PauseFor);
            }
            else
            {
                string datePlusTime = DateTime.Today.ToString("yyyy-MM-dd ") + this.PauseUntil;
                DateTime pauseUntilTime = Convert.ToDateTime(datePlusTime);
                TimeSpan pauseDuration = (pauseUntilTime - DateTime.Now);
                System.Threading.Thread.Sleep(pauseDuration);
            }

            return DTSExecResult.Success;
        }
        #endregion
        #endregion
    }
    #endregion
}
